import { CraftingRecipe, CraftingResult, ItemGrid, CraftingGrid } from './types';
import { BlockType } from '@/blocks/types';
import { Inventory } from '@/player/Inventory';
import { RecipeManager } from './RecipeManager';

export class CraftingSystem {
  private recipes: Map<string, CraftingRecipe> = new Map();
  private recipeManager: RecipeManager;

  constructor() {
    this.recipeManager = new RecipeManager();
    this.initializeBasicRecipes();
  }

  public registerRecipe(recipe: CraftingRecipe): void {
    this.recipes.set(recipe.id, recipe);
  }

  public checkRecipe(grid: CraftingGrid): CraftingResult | null {
    // 首先尝试匹配有形状的配方
    for (const recipe of this.recipes.values()) {
      if (recipe.type === 'shaped') {
        const result = this.matchShapedRecipe(grid, recipe);
        if (result) {
          return result;
        }
      }
    }

    // 然后尝试匹配无形状的配方
    for (const recipe of this.recipes.values()) {
      if (recipe.type === 'shapeless') {
        const result = this.matchShapelessRecipe(grid, recipe);
        if (result) {
          return result;
        }
      }
    }

    return null;
  }

  private matchShapedRecipe(grid: CraftingGrid, recipe: CraftingRecipe): CraftingResult | null {
    const recipePattern = recipe.pattern;
    const gridSize = grid.length;
    const patternHeight = recipePattern.length;
    const patternWidth = recipePattern[0]?.length || 0;

    // 尝试在网格中的每个位置匹配配方
    for (let startRow = 0; startRow <= gridSize - patternHeight; startRow++) {
      for (let startCol = 0; startCol <= gridSize - patternWidth; startCol++) {
        if (this.matchPatternAt(grid, recipePattern, startRow, startCol)) {
          return {
            recipe,
            canCraft: true
          };
        }
      }
    }

    return null;
  }

  private matchPatternAt(
    grid: CraftingGrid, 
    pattern: (BlockType | null)[][], 
    startRow: number, 
    startCol: number
  ): boolean {
    const gridSize = grid.length;
    const patternHeight = pattern.length;
    const patternWidth = pattern[0]?.length || 0;

    // 检查配方区域外的格子是否为空
    for (let row = 0; row < gridSize; row++) {
      for (let col = 0; col < gridSize; col++) {
        const inPatternArea = row >= startRow && row < startRow + patternHeight &&
                             col >= startCol && col < startCol + patternWidth;
        
        if (inPatternArea) {
          const patternRow = row - startRow;
          const patternCol = col - startCol;
          const expectedType = pattern[patternRow][patternCol];
          const actualType = grid[row][col].type;
          
          if (expectedType !== actualType) {
            return false;
          }
        } else {
          // 配方区域外应该为空
          if (grid[row][col].type !== null) {
            return false;
          }
        }
      }
    }

    return true;
  }

  private matchShapelessRecipe(grid: CraftingGrid, recipe: CraftingRecipe): CraftingResult | null {
    const requiredItems = new Map<BlockType, number>();
    const availableItems = new Map<BlockType, number>();

    // 统计配方需要的物品
    for (const row of recipe.pattern) {
      for (const item of row) {
        if (item !== null) {
          requiredItems.set(item, (requiredItems.get(item) || 0) + 1);
        }
      }
    }

    // 统计网格中可用的物品
    for (const row of grid) {
      for (const slot of row) {
        if (slot.type !== null) {
          availableItems.set(slot.type, (availableItems.get(slot.type) || 0) + slot.count);
        }
      }
    }

    // 检查是否有足够的物品
    for (const [itemType, needed] of requiredItems) {
      const available = availableItems.get(itemType) || 0;
      if (available < needed) {
        return null;
      }
    }

    // 检查是否有多余的物品
    for (const [itemType] of availableItems) {
      if (!requiredItems.has(itemType)) {
        return null;
      }
    }

    return {
      recipe,
      canCraft: true
    };
  }

  public executeRecipe(recipe: CraftingRecipe, inventory: Inventory, craftingGrid: CraftingGrid): boolean {
    // 检查是否可以合成
    const result = this.checkRecipe(craftingGrid);
    if (!result || result.recipe.id !== recipe.id) {
      return false;
    }

    // 消耗材料
    if (!this.consumeMaterials(craftingGrid, recipe)) {
      return false;
    }

    // 添加结果物品到物品栏
    const success = inventory.addItem(recipe.result.type, recipe.result.count);
    if (!success) {
      // 如果物品栏满了，恢复材料（这里简化处理）
      return false;
    }

    return true;
  }

  private consumeMaterials(craftingGrid: CraftingGrid, recipe: CraftingRecipe): boolean {
    if (recipe.type === 'shaped') {
      return this.consumeShapedMaterials(craftingGrid, recipe);
    } else {
      return this.consumeShapelessMaterials(craftingGrid, recipe);
    }
  }

  private consumeShapedMaterials(craftingGrid: CraftingGrid, recipe: CraftingRecipe): boolean {
    // 找到配方在网格中的位置
    const gridSize = craftingGrid.length;
    const patternHeight = recipe.pattern.length;
    const patternWidth = recipe.pattern[0]?.length || 0;

    for (let startRow = 0; startRow <= gridSize - patternHeight; startRow++) {
      for (let startCol = 0; startCol <= gridSize - patternWidth; startCol++) {
        if (this.matchPatternAt(craftingGrid, recipe.pattern, startRow, startCol)) {
          // 消耗材料
          for (let row = 0; row < patternHeight; row++) {
            for (let col = 0; col < patternWidth; col++) {
              const gridRow = startRow + row;
              const gridCol = startCol + col;
              if (recipe.pattern[row][col] !== null) {
                craftingGrid[gridRow][gridCol].count--;
                if (craftingGrid[gridRow][gridCol].count <= 0) {
                  craftingGrid[gridRow][gridCol].type = null;
                  craftingGrid[gridRow][gridCol].count = 0;
                }
              }
            }
          }
          return true;
        }
      }
    }

    return false;
  }

  private consumeShapelessMaterials(craftingGrid: CraftingGrid, recipe: CraftingRecipe): boolean {
    const requiredItems = new Map<BlockType, number>();

    // 统计需要消耗的物品
    for (const row of recipe.pattern) {
      for (const item of row) {
        if (item !== null) {
          requiredItems.set(item, (requiredItems.get(item) || 0) + 1);
        }
      }
    }

    // 消耗物品
    for (const [itemType, needed] of requiredItems) {
      let remaining = needed;
      for (const row of craftingGrid) {
        for (const slot of row) {
          if (slot.type === itemType && remaining > 0) {
            const consume = Math.min(slot.count, remaining);
            slot.count -= consume;
            remaining -= consume;
            if (slot.count <= 0) {
              slot.type = null;
              slot.count = 0;
            }
          }
        }
      }
      if (remaining > 0) {
        return false; // 材料不足
      }
    }

    return true;
  }

  private initializeBasicRecipes(): void {
    // 从RecipeManager加载所有配方
    const allRecipes = this.recipeManager.getAllRecipes();
    allRecipes.forEach(recipe => {
      this.registerRecipe(recipe);
    });
  }

  public getAllRecipes(): CraftingRecipe[] {
    return this.recipeManager.getAllRecipes();
  }

  public getRecipe(id: string): CraftingRecipe | undefined {
    return this.recipeManager.getRecipe(id);
  }

  public getRecipeManager(): RecipeManager {
    return this.recipeManager;
  }
}